package com.yamibuy.ec.resource.filter;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.yamibuy.ec.resource.handler.ExceptionHandler;
import com.yamibuy.ec.resource.handler.HandleSelector;
import com.yamibuy.ec.resource.handler.ImageHandler;
import com.yamibuy.ec.resource.handler.RequestHandlerFlag;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Globals;
import org.apache.catalina.connector.RequestFacade;
import org.springframework.http.MediaType;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;

/**
 * 过滤所有请求处理
 *
 * @author: damon.li
 * @version: 2021年02月21日 16:38
 */
@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "cdnFilter")
public class CdnFilter implements Filter {

	@Resource
	private ExceptionHandler exceptionHandler;

	@Resource
	private HandleSelector handleSelector;

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
		log.debug("=============path 处理开始 ============");
		RequestFacade requestFacade = (RequestFacade) servletRequest;
		String realPath = requestFacade.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR).toString();
		String covertPath = requestFacade.getRequestURI().replaceAll("/+","/");
		if ("/favicon.ico".equals(covertPath)) {
			return;
		}

		// 阿里云规则拼接
		String aliRule = requestFacade.getParameter("x-oss-process");
		if (StrUtil.isNotBlank(aliRule)) {
			realPath += ".webp" + "?x-oss-process=" + aliRule;
			covertPath += ".webp" + "?x-oss-process=" + aliRule;
		}
		log.debug("真实 PATH：{}", realPath);
		log.debug("转义 PATH：{}", covertPath);

		try {
			RequestHandlerFlag selector = handleSelector.selector(covertPath);
			ByteArrayOutputStream out =  selector.handle(covertPath);
			selector.responseHeader(servletResponse);
			try (
					ServletOutputStream outputStream = servletResponse.getOutputStream();
			) {
				outputStream.write(out.toByteArray());
			}

		} catch (Exception e) {
			// 异常处理
			try {
				log.error("真实 PATH：{}", realPath);
				log.error("转义 PATH：{}", covertPath);
				ByteArrayOutputStream out = exceptionHandler.handle(e);
				servletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
				servletResponse.setCharacterEncoding(Charset.defaultCharset().name());
				try (
						ServletOutputStream outputStream = servletResponse.getOutputStream();
				) {
					outputStream.write(out.toByteArray());
				}

			} catch (Exception exception) {
				exception.printStackTrace();
			}
		}
	}
}
